package icegps.com.pingdj.data.analysis;


import android.support.annotation.NonNull;

import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;

import icegps.com.pingdj.bean.DeviceStatus;
import icegps.com.pingdj.bean.LocationStatus;
import icegps.com.pingdj.bean.SatelliteData;
import icegps.com.pingdj.data.ble.WriteHelper;
import timber.log.Timber;


/**
 * Created by 111 on 2018/3/21.
 */

public class AnalysisHelper {
    private static AnalysisHelper analysisHelper;
    private final AnalysisHex analysisHex;
    private final AnalysisAsc analysisAsc;
    private CopyOnWriteArrayList<AnalysisCallback> callbacks;
    private DeviceStatus deviceStatus;

    public static AnalysisHelper getInstance() {

        if (analysisHelper == null) {
            synchronized (AnalysisHelper.class) {
                if (analysisHelper == null) {
                    analysisHelper = new AnalysisHelper();
                }
            }
        }
        return analysisHelper;
    }

    private AnalysisHelper() {
        deviceStatus = DeviceStatus.getDeviceStatus();
        callbacks = new CopyOnWriteArrayList<>();
        analysisAsc = new AnalysisAsc();
        analysisHex = new AnalysisHex();

        analysisAsc.setOnAscDataListener(new AnalysisAsc.OnAscDataListener() {
            @Override
            public void onData(String data) {
                Timber.e(data);
                analysisDeviceStatus(data);
                if (callbacks != null) {
                    for (AnalysisCallback callback : callbacks) {
                        callback.onAnalysisAscStringData(data);
                    }
                }
            }

            private synchronized void analysisDeviceStatus(String data) {
                try {
                    String[] cmds = splitAndRemoveAss(data);
                    if (data.contains(WriteHelper.KEY_RADIO)) {
                        deviceStatus.setMaxRadio(Integer.parseInt(cmds[3]));
                        deviceStatus.setMinRadio(Integer.parseInt(cmds[4]));
                        deviceStatus.setCurrentRadio(Integer.parseInt(cmds[5]));
                    } else if (data.contains(WriteHelper.KEY_INSMODE)) {
                        deviceStatus.setInsMode(Integer.parseInt(cmds[2]));
                    } else if (data.contains(WriteHelper.KEY_VERSION)) {
                        deviceStatus.setDeviceMode(cmds[2]);
                        deviceStatus.setDeviceImei(cmds[3]);
                        deviceStatus.setSoftwareVersion(cmds[4]);
                        deviceStatus.setCardMode(cmds[5]);
                        deviceStatus.setNumberMode(cmds[6]);
                        deviceStatus.setActivateInfo(cmds[7]);
                    } else if (data.contains(WriteHelper.KEY_CONTROL)) {
                        deviceStatus.setControlOne(Integer.parseInt(cmds[2]));
                        deviceStatus.setControlTwo(Integer.parseInt(cmds[3]));
                    } else if (data.contains(WriteHelper.KEY_BALANCE)) {
                        deviceStatus.setBalanceDifference(Double.parseDouble(cmds[2]));
                    } else if (data.contains(WriteHelper.KEY_ACCURACY)) {
                        float accuracy = Float.parseFloat(cmds[2]) / 10;
                        deviceStatus.setWorkAccuracy(accuracy + "");
                    } else if (data.contains(WriteHelper.KEY_BUCKETW)) {
                        float workWidth = Float.parseFloat(cmds[2]);
                        deviceStatus.setWorkWidth(workWidth);
                    } else if (data.contains(WriteHelper.KEY_ANTENNAP)) {
                        float antennaLocation = Float.parseFloat(cmds[2]);
                        deviceStatus.setAntennaLocation(antennaLocation);
                    } else if (data.contains(WriteHelper.KEY_GRADER)) {
                        deviceStatus.setWorkAction(Integer.parseInt(cmds[2]));
                        deviceStatus.setWorkMode(Integer.parseInt(cmds[3]));
                        deviceStatus.setTragetHeight1(Double.parseDouble(cmds[4]));
                        deviceStatus.setCurrentTimedifference1(Double.parseDouble(cmds[5]));
                        deviceStatus.setControlOne(Integer.parseInt(cmds[6]));
                        deviceStatus.setTragetHeight2(Double.parseDouble(cmds[7]));
                        deviceStatus.setCurrentTimedifference2(Double.parseDouble(cmds[8]));
                        deviceStatus.setControlTwo(Integer.parseInt(cmds[9]));
                    } else {
                        return;
                    }
                } catch (IndexOutOfBoundsException e) {
                    e.printStackTrace();
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }
                for (AnalysisCallback callback : callbacks) {
                    callback.onAnalysisAscDeviceStatus(deviceStatus);
                }
            }
        });

        analysisHex.setOnHexDataListener(new AnalysisHex.OnHexDataListener() {
            @Override
            public void onLocationData(LocationStatus locationStatus) {
                if (callbacks != null) {
                    for (AnalysisCallback callback : callbacks) {
                        callback.onAnalysisHexLocationData(locationStatus);
                    }
                }
            }

            @Override
            public void onSatelliteData(ArrayList<SatelliteData> satelliteDatas, byte type) {
                if (callbacks != null) {
                    for (AnalysisCallback callback : callbacks) {
                        callback.onAnalysisHexSatelliteData(satelliteDatas, type);
                    }
                }
            }
        });
    }

    @NonNull
    private String[] splitAndRemoveAss(String data) {
        String[] split = data.split("\\*");
        return split[0].split(",");
    }

    public void addAnalysisHelper(AnalysisCallback analysisCallback) {
        if (!callbacks.contains(analysisCallback))
            callbacks.add(analysisCallback);
    }

    public void removeAnalysisHelper(AnalysisCallback analysisCallback) {
        callbacks.remove(analysisCallback);
    }

    public void notify(byte[] bytes) {
        for (byte b : bytes) {

            if (analysisHex.isAdd()) {
                analysisHex.analysisData(b);
            } else if (analysisAsc.isAdd()) {
                analysisAsc.analysisData(b);
            } else {
                analysisHex.analysisData(b);
                analysisAsc.analysisData(b);
            }
        }
    }

}
